#include <iostream>
#include <string>
#include <bitset>
#include <cctype>
#include <sstream>
#include <vector>
#include <cstdint>

#include "button_trigger.hpp"


using namespace button_trigger;

using ButtonTriggerType = ButtonTrigger<>;


std::string get_buffer_binary(const ButtonTriggerType &button) {
    return std::bitset<sizeof(ButtonTriggerType::BitBufferType) * 8>(button.get_bit_buffer()).to_string();
}


/**
 * @brief 分割字符串为命令列表
 */
std::vector<std::string> split_commands(const std::string& input) {
    std::vector<std::string> commands;
    std::stringstream ss(input);
    std::string token;
    
    while (ss >> token) {
        commands.push_back(token);
    }
    
    return commands;
}


/**
 * @brief 处理单个命令
 */
void process_command(char cmd, ButtonTriggerType& button) {
    switch (cmd) {
        case 'R':
            button.reset();
            std::cout << "RESET" << std::endl;
            break;
            
        case 'D':
        case 'F':
            {
                bool level = (cmd == 'F'); // D: 按下(低电平false), F: 抬起(高电平true)
                std::string level_str = level ? "HIGH" : "LOW";
                
                std::cout << "INPUT: " << cmd << " (" << level_str << ")" << std::endl;
                
                button.feed_negative(level);
                
                // 输出缓冲区状态
                std::cout << "BUFFER: " << get_buffer_binary(button) << std::endl;
                
                // 检查并输出事件
                if (button.pressed()) {
                    std::cout << "*** EVENT: PRESSED ***" << std::endl;
                }
                if (button.released()) {
                    std::cout << "*** EVENT: RELEASED ***" << std::endl;
                }
                if (button.clicked()) {
                    std::cout << "*** EVENT: CLICKED ***" << std::endl;
                }
                if (button.long_pressed()) {
                    std::cout << "*** EVENT: LONG_PRESSED ***" << std::endl;
                }                
            }
            break;
            
        default:
            break;
    }
}


// 测试程序
int main() {
    // 创建按键事件对象，使用默认参数
    ButtonTriggerType button;
    
    std::cout << "Button Trigger Simulator" << std::endl;
    std::cout << "Command:" << std::endl;
    std::cout << "  D - press" << std::endl;
    std::cout << "  F - release" << std::endl;
    std::cout << "  R - reset button filter" << std::endl;
    std::cout << "  Q - quit" << std::endl;
    std::cout << "Long press threshold: " << 10 << std::endl;
    std::cout << "debounce period: " << 2 << std::endl;
    std::cout << "----------------------------------------" << std::endl;
    
    std::string input;
    while (true) {
        std::cout << ">> (D/F/R/Q): ";
        std::getline(std::cin, input);
        
        if (input.empty()) {
            continue;
        }
        
        // 检查是否退出
        if (std::toupper(input[0]) == 'Q') {
            std::cout << "Quit" << std::endl;
            return 0;
        }
        
        // 分割输入为多个命令
        std::vector<std::string> commands = split_commands(input);
        
        
        // 依次处理每个命令
        for (const auto& cmd_str : commands) {
            if (cmd_str.empty()) continue;
            
            char cmd = std::toupper(cmd_str[0]);
            process_command(cmd, button);
            std::cout << "---" << std::endl;
        }
        
        std::cout << std::endl;
    }
    
    return 0;
}
